#!/usr/bin/env python3
"""
基于已知映射推断算法
"""

def analyze_known_mappings():
    """深入分析已知的映射关系"""
    print("🧮 === 分析映射算法 ===\n")
    
    # 已知的映射
    mappings = [
        (0xa1, ord('m'), "m"),  # 161 -> 109
        (0xf3, ord('o'), "o"),  # 243 -> 111
        (0x6b, ord('d'), "d"),  # 107 -> 100
        (0x31, ord('e'), "e"),  # 49 -> 101
        (0xb0, ord('l'), "l"),  # 176 -> 108
        (0x69, ord('"'), '"'),  # 105 -> 34
        (0x01, ord(':'), ":"),  # 1 -> 58
        (0x90, ord(' '), " ")   # 144 -> 32
    ]
    
    print("已知映射分析:")
    print("密文 -> 明文 | 差值 | 密文二进制 | 明文二进制")
    print("-" * 70)
    
    for enc, dec, char in mappings:
        diff = dec - enc
        enc_bin = format(enc, '08b')
        dec_bin = format(dec, '08b')
        xor = enc ^ dec
        
        print(f"0x{enc:02x}({enc:3d}) -> 0x{dec:02x}({dec:3d}) '{char}' | "
              f"{diff:4d} | {enc_bin} | {dec_bin} | XOR: 0x{xor:02x}")
    
    # 分析XOR模式
    print("\n\nXOR分析:")
    xor_values = [(enc ^ dec, enc, dec, char) for enc, dec, char in mappings]
    
    for xor_val, enc, dec, char in sorted(xor_values):
        print(f"0x{enc:02x} ^ 0x{dec:02x} = 0x{xor_val:02x} ({xor_val:3d}) -> '{char}'")
    
    # 查找模式
    print("\n\n寻找数学关系...")
    
    # 尝试分组
    print("\n按字符类型分组:")
    
    letters = [(e, d, c) for e, d, c in mappings if c.isalpha()]
    special = [(e, d, c) for e, d, c in mappings if not c.isalpha()]
    
    print("\n字母:")
    for enc, dec, char in letters:
        print(f"  {char}: 0x{enc:02x} -> 0x{dec:02x}")
    
    print("\n特殊字符:")
    for enc, dec, char in special:
        print(f"  {char}: 0x{enc:02x} -> 0x{dec:02x}")

def generate_mapping_table():
    """基于分析生成可能的映射表"""
    print("\n\n🔨 === 生成映射表 ===")
    
    # 基于已知映射，尝试推断完整映射
    known = {
        0xa1: ord('m'),
        0xf3: ord('o'),
        0x6b: ord('d'),
        0x31: ord('e'),
        0xb0: ord('l'),
        0x69: ord('"'),
        0x01: ord(':'),
        0x90: ord(' ')
    }
    
    # 创建初始映射表
    mapping_table = list(range(256))
    
    # 应用已知映射
    for enc, dec in known.items():
        mapping_table[enc] = dec
    
    # 尝试推断其他映射
    # 基于观察：似乎是某种置换密码
    
    # 方法1: 假设是基于某种规则的置换
    print("\n尝试不同的映射策略...")
    
    # 策略1: 简单的字节替换表
    # 从二进制文件中查找可能的替换表
    
    # 策略2: 基于已知映射推断
    # 观察到的模式可能有规律
    
    # 应用映射测试
    test_decryption(mapping_table, "initial_mapping")
    
    # 尝试其他策略
    try_pattern_based_mapping()

def try_pattern_based_mapping():
    """尝试基于模式的映射"""
    print("\n\n🎯 === 基于模式的映射 ===")
    
    # 我们知道JSON中常见的模式
    # "questionText": 
    # "conversationId":
    # "sessionId":
    # "userId":
    
    with open('decoded_result.bin', 'rb') as f:
        data = f.read()
    
    # 查找重复的模式
    # 0x69 是引号，0x01 是冒号
    quote = 0x69
    colon = 0x01
    
    # 查找 "xxx": 模式
    patterns = []
    i = 0
    while i < len(data) - 10:
        if data[i] == quote:
            # 找下一个引号
            j = i + 1
            while j < len(data) and data[j] != quote:
                j += 1
            
            if j < len(data) - 1 and data[j+1] == colon:
                # 找到一个字段
                field = data[i+1:j]
                if 4 <= len(field) <= 20:  # 合理的字段长度
                    patterns.append(field)
            i = j + 1
        else:
            i += 1
    
    # 统计最常见的字段
    from collections import Counter
    field_counter = Counter(patterns)
    
    print(f"找到 {len(field_counter)} 个不同的字段模式")
    print("\n最常见的字段（加密后）:")
    
    common_fields = field_counter.most_common(10)
    for field, count in common_fields:
        print(f"  {field.hex()}: {count}次 (长度 {len(field)})")
    
    # 尝试匹配已知字段名
    known_fields = [
        b"questionText",    # 12字符
        b"conversationId",  # 14字符
        b"sessionId",       # 9字符
        b"userId",          # 6字符
        b"content",         # 7字符
        b"message",         # 7字符
        b"status",          # 6字符
        b"type",            # 4字符
        b"data",            # 4字符
        b"code",            # 4字符
        b"name",            # 4字符
        b"text"             # 4字符
    ]
    
    # 创建新的映射
    extended_mapping = {
        0xa1: ord('m'),
        0xf3: ord('o'),
        0x6b: ord('d'),
        0x31: ord('e'),
        0xb0: ord('l'),
        0x69: ord('"'),
        0x01: ord(':'),
        0x90: ord(' ')
    }
    
    # 尝试匹配
    for enc_field, count in common_fields:
        field_len = len(enc_field)
        
        # 查找相同长度的已知字段
        candidates = [f for f in known_fields if len(f) == field_len]
        
        if candidates:
            print(f"\n字段 {enc_field.hex()} (长度{field_len}, 出现{count}次)")
            print(f"可能匹配: {[c.decode() for c in candidates]}")
            
            # 对每个候选进行验证
            for candidate in candidates:
                # 检查已知字符是否匹配
                match = True
                new_mappings = {}
                
                for i in range(field_len):
                    enc_byte = enc_field[i]
                    dec_byte = candidate[i]
                    
                    if enc_byte in extended_mapping:
                        if extended_mapping[enc_byte] != dec_byte:
                            match = False
                            break
                    else:
                        new_mappings[enc_byte] = dec_byte
                
                if match and len(new_mappings) > 0:
                    print(f"  ✓ 可能是 '{candidate.decode()}'")
                    # 添加新映射
                    for k, v in new_mappings.items():
                        if k not in extended_mapping:
                            extended_mapping[k] = v
                            print(f"    新映射: 0x{k:02x} -> '{chr(v)}'")
    
    # 使用扩展映射解密
    print(f"\n\n使用扩展映射 ({len(extended_mapping)} 个字符)...")
    
    mapping_table = list(range(256))
    for enc, dec in extended_mapping.items():
        mapping_table[enc] = dec
    
    test_decryption(mapping_table, "extended_mapping")

def test_decryption(mapping_table, name):
    """测试映射表"""
    print(f"\n测试映射表: {name}")
    
    with open('decoded_result.bin', 'rb') as f:
        data = f.read()
    
    # 解密
    decrypted = bytearray()
    for byte in data:
        decrypted.append(mapping_table[byte])
    
    # 统计
    mapped_count = sum(1 for i in range(256) if mapping_table[i] != i)
    printable = sum(1 for b in decrypted[:1000] if 32 <= b <= 126)
    
    print(f"  映射了 {mapped_count} 个字符")
    print(f"  前1000字节中可打印字符: {printable}")
    
    # 检查JSON特征
    json_count = 0
    if b'{"' in decrypted[:100]:
        json_count += 1
    if b'": ' in decrypted[:500]:
        json_count += 1
    if b'"model"' in decrypted[:500]:
        json_count += 1
    
    print(f"  JSON特征: {json_count}/3")
    
    # 保存结果
    filename = f'decrypt_attempt_{name}.txt'
    with open(filename, 'wb') as f:
        f.write(decrypted)
    
    # 显示预览
    preview = bytearray()
    for b in decrypted[:300]:
        if 32 <= b <= 126:
            preview.append(b)
        else:
            preview.append(ord('?'))
    
    print(f"  预览: {bytes(preview).decode('ascii')[:150]}...")
    
    return decrypted

def final_analysis():
    """最终分析"""
    print("\n\n📊 === 最终分析 ===")
    
    print("\n基于分析，这个加密方案：")
    print("1. 使用了简单的字节替换（substitution cipher）")
    print("2. 每个字节值映射到另一个固定的字节值")
    print("3. 映射表包含256个条目")
    print("4. 映射表可能：")
    print("   a) 硬编码在二进制文件中")
    print("   b) 动态生成（基于某个密钥或算法）")
    print("   c) 从外部配置加载")
    
    print("\n由于没有在二进制中找到完整的映射表，")
    print("最可能的情况是映射表是动态生成的。")
    
    print("\n建议的解决方案：")
    print("1. 使用调试器在运行时捕获映射表")
    print("2. 收集更多的明文-密文对来重建映射表")
    print("3. 分析二进制中的表生成算法")

if __name__ == "__main__":
    analyze_known_mappings()
    generate_mapping_table()
    final_analysis()
    
    print("\n\n✅ 分析完成!")
    print("查看 decrypt_attempt_*.txt 文件了解解密尝试结果")